package com.heima.se.sjms.代理;

/*
    代理模式   -- 装饰者模式
       作用：可以在不修改一个类的代码前提下，对类的功能进行增强。


    实现方式：
        1. jdk动态代理： Proxy.newProxyInstance()
        2. cjlib动态代理：Enhancer实现

    区别：

 */

import org.springframework.cglib.proxy.Enhancer;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

public class Demo {
    public static void main(String[] args) {
        //原始对象
        List<String> list = new ArrayList<>();

        //需求： 在不改变List源码的基础上，对List的add功能进行增强
        //增强效果：只添加长度 > 5的字符串，对于长度小于5忽略添加
        //基于jdk动态代理实现
        //代理对象
        /*
            参数1： list.getClass().getClassLoader()   ： 原始对象类加载器，固定写法
            参数2： list.getClass().getInterfaces()   ： 原始对象实现的接口数组，固定写法
            参数3： new InvocationHandler() {}   ： 代理对象方法调用的事件监听，固定写法
         */
        List proxyList = (List) Proxy.newProxyInstance(list.getClass().getClassLoader(),
                list.getClass().getInterfaces(),
                new InvocationHandler() {       //事件回调

                    /*
                        参数1： Object proxy  ： 指代代理对象本身，方法内不能使用，避免递归调用导致栈溢出
                        参数2： Method method  ： 本次拿代理对象调用的方法对象
                        参数3： Object[] args  ： 本次拿代理对象调用的方法所携带的参数
                     */
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //对add的功能进行增强
                        if ("add".equals(method.getName())) {
                            String arg = (String) args[0];
                            if (arg.length() <= 5) {
                                return false;
                            }

                        }
                        //其他功能不做干预，直接调用原始对象功能
                        return method.invoke(list, args);
                    }
                });

        proxyList.add("12345");
        proxyList.add("123456789");
        proxyList.add("12345678910");

        System.out.println("list = " + list);

    }
}
